const Project = require('../models/Project');
const { catchAsync } = require('../utils/errorHandler');

// 创建新项目
exports.createProject = catchAsync(async (req, res) => {
  const { title, description, content, thumbnail, isPublic, tags, category, difficulty } = req.body;

  // 验证和处理content结构
  let processedContent = {
    blocks: '',
    sprites: [],
    stage: {},
    scene: {} // 新增3D场景数据
  };

  if (content) {
    // 处理Blockly XML数据
    if (content.blocks) {
      processedContent.blocks = content.blocks;
    }
    
    // 处理3D场景数据
    if (content.scene) {
      processedContent.scene = content.scene;
    }
    
    // 保持原有的sprites和stage数据
    if (content.sprites) {
      processedContent.sprites = content.sprites;
    }
    
    if (content.stage) {
      processedContent.stage = content.stage;
    }
  }

  // 创建项目
  const project = await Project.create({
    title,
    description,
    creator: req.user.id,
    content: processedContent,
    thumbnail,
    isPublic,
    tags,
    category,
    difficulty,
  });

  res.status(201).json({
    success: true,
    message: '项目创建成功',
    data: { project },
  });
});

// 获取项目详情
exports.getProject = catchAsync(async (req, res) => {
  const project = await Project.findById(req.params.id)
    .populate('creator', 'username avatar')
    .populate('collaborators.user', 'username avatar');

  if (!project) {
    return res.status(404).json({
      success: false,
      message: '项目不存在',
    });
  }

  // 检查访问权限
  const isCreator = project.creator._id.toString() === req.user.id;
  const isCollaborator = project.collaborators.some(
    (collab) => collab.user._id.toString() === req.user.id
  );

  if (!project.isPublic && !isCreator && !isCollaborator) {
    return res.status(403).json({
      success: false,
      message: '您没有权限访问此项目',
    });
  }

  // 更新浏览量
  if (!isCreator) {
    project.stats.views += 1;
    await project.save({ validateBeforeSave: false });
  }

  res.status(200).json({
    success: true,
    data: { project },
  });
});

// 更新项目
exports.updateProject = catchAsync(async (req, res) => {
  const { title, description, content, isPublic, tags, category, difficulty } = req.body;

  // 查找项目
  let project = await Project.findById(req.params.id);

  if (!project) {
    return res.status(404).json({
      success: false,
      message: '项目不存在',
    });
  }

  // 检查权限
  const isCreator = project.creator.toString() === req.user.id;
  const isEditor = project.collaborators.some(
    (collab) => collab.user.toString() === req.user.id && ['editor', 'admin'].includes(collab.role)
  );

  if (!isCreator && !isEditor) {
    return res.status(403).json({
      success: false,
      message: '您没有权限更新此项目',
    });
  }

  // 保存历史版本
  if (content && !project.content.equals(content)) {
    project.history.push({
      version: project.version,
      content: project.content,
      updatedBy: req.user.id,
      timestamp: Date.now(),
      comment: req.body.versionComment || `版本 ${project.version} 更新`,
    });
    project.version += 1;
  }

  // 更新项目
  project = await Project.findByIdAndUpdate(
    req.params.id,
    {
      title,
      description,
      content,
      isPublic,
      tags,
      category,
      difficulty,
    },
    {
      new: true,
      runValidators: true,
    }
  );

  res.status(200).json({
    success: true,
    message: '项目更新成功',
    data: { project },
  });
});

// 删除项目
exports.deleteProject = catchAsync(async (req, res) => {
  const project = await Project.findById(req.params.id);

  if (!project) {
    return res.status(404).json({
      success: false,
      message: '项目不存在',
    });
  }

  // 检查权限
  const isCreator = project.creator.toString() === req.user.id;
  const isAdmin = project.collaborators.some(
    (collab) => collab.user.toString() === req.user.id && collab.role === 'admin'
  );

  if (!isCreator && !isAdmin) {
    return res.status(403).json({
      success: false,
      message: '您没有权限删除此项目',
    });
  }

  await project.remove();

  res.status(200).json({
    success: true,
    message: '项目删除成功',
    data: null,
  });
});

// 获取用户的项目列表
exports.getUserProjects = catchAsync(async (req, res) => {
  const userId = req.params.userId || req.user.id;
  const page = parseInt(req.query.page, 10) || 1;
  const limit = parseInt(req.query.limit, 10) || 10;
  const skip = (page - 1) * limit;

  // 构建查询条件
  const query = { creator: userId };
  
  // 如果不是查询自己的项目，只显示公开项目
  if (userId !== req.user.id) {
    query.isPublic = true;
  }

  // 执行查询
  const projects = await Project.find(query)
    .sort({ createdAt: -1 })
    .skip(skip)
    .limit(limit)
    .select('title description thumbnail isPublic category difficulty stats createdAt updatedAt');

  // 获取总数
  const total = await Project.countDocuments(query);

  res.status(200).json({
    success: true,
    data: {
      projects,
      pagination: {
        total,
        page,
        limit,
        pages: Math.ceil(total / limit),
      },
    },
  });
});

// 获取公开项目列表
exports.getPublicProjects = catchAsync(async (req, res) => {
  const page = parseInt(req.query.page, 10) || 1;
  const limit = parseInt(req.query.limit, 10) || 10;
  const skip = (page - 1) * limit;

  // 构建查询条件
  const query = { isPublic: true };
  
  // 过滤条件
  if (req.query.category) query.category = req.query.category;
  if (req.query.difficulty) query.difficulty = req.query.difficulty;
  if (req.query.tags) query.tags = { $in: req.query.tags.split(',') };

  // 排序条件
  let sort = { createdAt: -1 }; // 默认按创建时间降序
  if (req.query.sort) {
    switch (req.query.sort) {
      case 'popular':
        sort = { 'stats.views': -1 };
        break;
      case 'likes':
        sort = { 'stats.likes': -1 };
        break;
      case 'newest':
        sort = { createdAt: -1 };
        break;
      default:
        sort = { createdAt: -1 };
    }
  }

  // 执行查询
  const projects = await Project.find(query)
    .sort(sort)
    .skip(skip)
    .limit(limit)
    .populate('creator', 'username avatar')
    .select('title description thumbnail category difficulty stats createdAt');

  // 获取总数
  const total = await Project.countDocuments(query);

  res.status(200).json({
    success: true,
    data: {
      projects,
      pagination: {
        total,
        page,
        limit,
        pages: Math.ceil(total / limit),
      },
    },
  });
});

// 添加协作者
exports.addCollaborator = catchAsync(async (req, res) => {
  const { userId, role } = req.body;

  // 查找项目
  const project = await Project.findById(req.params.id);

  if (!project) {
    return res.status(404).json({
      success: false,
      message: '项目不存在',
    });
  }

  // 检查权限
  const isCreator = project.creator.toString() === req.user.id;
  const isAdmin = project.collaborators.some(
    (collab) => collab.user.toString() === req.user.id && collab.role === 'admin'
  );

  if (!isCreator && !isAdmin) {
    return res.status(403).json({
      success: false,
      message: '您没有权限添加协作者',
    });
  }

  // 检查用户是否已经是协作者
  const existingCollaborator = project.collaborators.find(
    (collab) => collab.user.toString() === userId
  );

  if (existingCollaborator) {
    return res.status(400).json({
      success: false,
      message: '该用户已经是协作者',
    });
  }

  // 添加协作者
  project.collaborators.push({
    user: userId,
    role: role || 'viewer',
    joinedAt: Date.now(),
  });

  await project.save();

  res.status(200).json({
    success: true,
    message: '协作者添加成功',
    data: { project },
  });
});

// 更新协作者角色
exports.updateCollaborator = catchAsync(async (req, res) => {
  const { userId, role } = req.body;

  // 查找项目
  const project = await Project.findById(req.params.id);

  if (!project) {
    return res.status(404).json({
      success: false,
      message: '项目不存在',
    });
  }

  // 检查权限
  const isCreator = project.creator.toString() === req.user.id;
  const isAdmin = project.collaborators.some(
    (collab) => collab.user.toString() === req.user.id && collab.role === 'admin'
  );

  if (!isCreator && !isAdmin) {
    return res.status(403).json({
      success: false,
      message: '您没有权限更新协作者角色',
    });
  }

  // 查找协作者
  const collaboratorIndex = project.collaborators.findIndex(
    (collab) => collab.user.toString() === userId
  );

  if (collaboratorIndex === -1) {
    return res.status(404).json({
      success: false,
      message: '协作者不存在',
    });
  }

  // 更新协作者角色
  project.collaborators[collaboratorIndex].role = role;

  await project.save();

  res.status(200).json({
    success: true,
    message: '协作者角色更新成功',
    data: { project },
  });
});

// 移除协作者
exports.removeCollaborator = catchAsync(async (req, res) => {
  const { userId } = req.params;

  // 查找项目
  const project = await Project.findById(req.params.id);

  if (!project) {
    return res.status(404).json({
      success: false,
      message: '项目不存在',
    });
  }

  // 检查权限
  const isCreator = project.creator.toString() === req.user.id;
  const isAdmin = project.collaborators.some(
    (collab) => collab.user.toString() === req.user.id && collab.role === 'admin'
  );

  if (!isCreator && !isAdmin) {
    return res.status(403).json({
      success: false,
      message: '您没有权限移除协作者',
    });
  }

  // 移除协作者
  project.collaborators = project.collaborators.filter(
    (collab) => collab.user.toString() !== userId
  );

  await project.save();

  res.status(200).json({
    success: true,
    message: '协作者移除成功',
    data: { project },
  });
});

// 点赞项目
exports.likeProject = catchAsync(async (req, res) => {
  // 查找项目
  const project = await Project.findById(req.params.id);

  if (!project) {
    return res.status(404).json({
      success: false,
      message: '项目不存在',
    });
  }

  // 增加点赞数
  project.stats.likes += 1;
  await project.save({ validateBeforeSave: false });

  res.status(200).json({
    success: true,
    message: '项目点赞成功',
    data: {
      likes: project.stats.likes,
    },
  });
});

// 获取项目历史版本
exports.getProjectHistory = catchAsync(async (req, res) => {
  const project = await Project.findById(req.params.id)
    .select('history')
    .populate('history.updatedBy', 'username avatar');

  if (!project) {
    return res.status(404).json({
      success: false,
      message: '项目不存在',
    });
  }

  // 检查访问权限
  const isCreator = project.creator.toString() === req.user.id;
  const isCollaborator = project.collaborators.some(
    (collab) => collab.user.toString() === req.user.id
  );

  if (!isCreator && !isCollaborator) {
    return res.status(403).json({
      success: false,
      message: '您没有权限查看此项目的历史版本',
    });
  }

  res.status(200).json({
    success: true,
    data: {
      history: project.history,
    },
  });
});

// 恢复项目到历史版本
exports.restoreProjectVersion = catchAsync(async (req, res) => {
  const { version } = req.params;

  // 查找项目
  const project = await Project.findById(req.params.id);

  if (!project) {
    return res.status(404).json({
      success: false,
      message: '项目不存在',
    });
  }

  // 检查权限
  const isCreator = project.creator.toString() === req.user.id;
  const isEditor = project.collaborators.some(
    (collab) => collab.user.toString() === req.user.id && ['editor', 'admin'].includes(collab.role)
  );

  if (!isCreator && !isEditor) {
    return res.status(403).json({
      success: false,
      message: '您没有权限恢复此项目的历史版本',
    });
  }

  // 查找历史版本
  const historyVersion = project.history.find((h) => h.version.toString() === version);

  if (!historyVersion) {
    return res.status(404).json({
      success: false,
      message: '历史版本不存在',
    });
  }

  // 保存当前版本到历史记录
  project.history.push({
    version: project.version,
    content: project.content,
    updatedBy: req.user.id,
    timestamp: Date.now(),
    comment: `版本 ${project.version} 保存（恢复到版本 ${version} 之前）`,
  });

  // 恢复到历史版本
  project.content = historyVersion.content;
  project.version += 1;

  await project.save();

  res.status(200).json({
    success: true,
    message: `项目已恢复到版本 ${version}`,
    data: { project },
  });
});